1 // DerelictCL - a Derelict based dynamic binding for OpenCL
2 // written in the D programming language
3 //
4 // Copyright: MeinMein 2013-2014.
5 // License:   Boost License 1.0
6 //            (See accompanying file LICENSE_1_0.txt or copy at
7 //             http://www.boost.org/LICENSE_1_0.txt)
8 // Authors:   Gerbrand Kamphuis (meinmein.com),
9 //            Marvin Meeng (meinmein.com).
10 module derelict.opencl.cl;
11 
12 public
13 {
14     import derelict.util.exception;
15 
16     import derelict.opencl.types;
17     import derelict.opencl.constants;
18     import derelict.opencl.functions;
19 
20     import derelict.opencl.cl_ext;
21     import derelict.opencl.cl_egl;
22     import derelict.opencl.cl_gl;
23     import derelict.opencl.cl_gl_ext;
24     import derelict.opencl.cl_d3d10;
25     import derelict.opencl.cl_d3d11;
26     import derelict.opencl.cl_dx9_media_sharing;
27 }
28 
29 private
30 {
31     import std.algorithm;
32     import std.conv;
33 
34     import derelict.util.loader;
35     import derelict.util.system;
36 
37     static if(Derelict_OS_Windows)
38     {
39         enum libNames = "opencl.dll";
40     }
41     else static if(Derelict_OS_Mac)
42     {
43         enum libNames = "../Frameworks/OpenCL.framework/OpenCL, /Library/Frameworks/OpenCL.framework/OpenCL, /System/Library/Frameworks/OpenCL.framework/OpenCL";
44     }
45     else static if(Derelict_OS_Posix)
46     {
47         enum libNames = "libOpenCL.so.1,libOpenCL.so";
48     }
49     else
50         static assert(0, "Need to implement OpenCL libNames for this operating system.");
51 }
52 
53 class DerelictCLLoader : SharedLibLoader
54 {
55     public
56     {
57         CLVersion loadedVersion() @property
58         {
59             return _loadedVersion;
60         }
61 
62         CLVersion reload(CLVersion clVer)
63         {
64             // CLVersion depends on chosen platform & device.
65             // Here we assume this is handled by the developer.
66 
67             // (Alternatively, a CLContext could be passed as argument,
68             // and then the lowest found CLVersion in its devices could be used.)
69 
70             if(clVer <= CLVersion.CL10)
71             {
72                 // OpenCL 1.0 Deprecated in 1.1
73                 bindFunc(cast(void**)&clSetCommandQueueProperty, "clSetCommandQueueProperty");
74             }
75 
76             if(clVer >= CLVersion.CL11)
77             {
78                 // OpenCL 1.1
79                 bindFunc(cast(void**)&clCreateSubBuffer, "clCreateSubBuffer");
80                 bindFunc(cast(void**)&clSetMemObjectDestructorCallback, "clSetMemObjectDestructorCallback");
81                 bindFunc(cast(void**)&clCreateUserEvent, "clCreateUserEvent");
82                 bindFunc(cast(void**)&clSetUserEventStatus, "clSetUserEventStatus");
83                 bindFunc(cast(void**)&clSetEventCallback, "clSetEventCallback");
84                 bindFunc(cast(void**)&clEnqueueReadBufferRect, "clEnqueueReadBufferRect");
85                 bindFunc(cast(void**)&clEnqueueWriteBufferRect, "clEnqueueWriteBufferRect");
86                 bindFunc(cast(void**)&clEnqueueCopyBufferRect, "clEnqueueCopyBufferRect");
87             }
88 
89             if(clVer <= CLVersion.CL11)
90             {
91                 // OpenCL 1.1 Deprecated in 1.2
92                 bindFunc(cast(void**)&clCreateImage2D, "clCreateImage2D");
93                 bindFunc(cast(void**)&clCreateImage3D, "clCreateImage3D");
94                 bindFunc(cast(void**)&clEnqueueMarker, "clEnqueueMarker");
95                 bindFunc(cast(void**)&clEnqueueWaitForEvents, "clEnqueueWaitForEvents");
96                 bindFunc(cast(void**)&clEnqueueBarrier, "clEnqueueBarrier");
97                 bindFunc(cast(void**)&clUnloadCompiler, "clUnloadCompiler");
98                 bindFunc(cast(void**)&clGetExtensionFunctionAddress, "clGetExtensionFunctionAddress");
99             }
100 
101             if(clVer >= CLVersion.CL12)
102             {
103                 // OpenCL 1.2
104                 bindFunc(cast(void**)&clCreateSubDevices, "clCreateSubDevices");
105                 bindFunc(cast(void**)&clRetainDevice, "clRetainDevice");
106                 bindFunc(cast(void**)&clReleaseDevice, "clReleaseDevice");
107                 bindFunc(cast(void**)&clCreateImage, "clCreateImage");
108                 bindFunc(cast(void**)&clCreateProgramWithBuiltInKernels, "clCreateProgramWithBuiltInKernels");
109                 bindFunc(cast(void**)&clCompileProgram, "clCompileProgram");
110                 bindFunc(cast(void**)&clLinkProgram, "clLinkProgram");
111                 bindFunc(cast(void**)&clUnloadPlatformCompiler, "clUnloadPlatformCompiler");
112                 bindFunc(cast(void**)&clGetKernelArgInfo, "clGetKernelArgInfo");
113                 bindFunc(cast(void**)&clEnqueueFillBuffer, "clEnqueueFillBuffer");
114                 bindFunc(cast(void**)&clEnqueueFillImage, "clEnqueueFillImage");
115                 bindFunc(cast(void**)&clEnqueueMigrateMemObjects, "clEnqueueMigrateMemObjects");
116                 bindFunc(cast(void**)&clEnqueueMarkerWithWaitList, "clEnqueueMarkerWithWaitList");
117                 bindFunc(cast(void**)&clEnqueueBarrierWithWaitList, "clEnqueueBarrierWithWaitList");
118                 bindFunc(cast(void**)&clGetExtensionFunctionAddressForPlatform, "clGetExtensionFunctionAddressForPlatform");
119             }
120 
121             derelict.opencl.cl_ext.reload(&bindFunc, clVer);
122             derelict.opencl.cl_gl_ext.reload(&bindFunc, clVer);
123             derelict.opencl.cl_gl.reload(&bindFunc, clVer);
124             
125             if(Derelict_OS_Windows)
126             {
127                 derelict.opencl.cl_d3d10.reload(&bindFunc, clVer);
128                 derelict.opencl.cl_d3d11.reload(&bindFunc, clVer);
129                 derelict.opencl.cl_dx9_media_sharing.reload(&bindFunc, clVer);
130             }
131 
132             _loadedVersion = clVer;
133             return clVer;
134         }
135 
136         // Load official extensions
137         // In OpenCL 1.2 this is cl_platform dependent
138         void loadEXT(cl_platform_id platform = null)
139         {
140             if(_loadedVersion >= CLVersion.CL12 && platform is null)
141                 throw new DerelictException(`OpenCL 1.2 requires a cl_platform_id to load official extension functions`);
142 
143             derelict.opencl.cl_ext.loadEXT(_loadedVersion, platform);
144             derelict.opencl.cl_egl.loadEXT(_loadedVersion, platform);
145             derelict.opencl.cl_gl_ext.loadEXT(_loadedVersion, platform);
146             derelict.opencl.cl_gl.loadEXT(_loadedVersion, platform);
147             
148             if(Derelict_OS_Windows)
149             {
150                 derelict.opencl.cl_d3d10.loadEXT(_loadedVersion, platform);
151                 derelict.opencl.cl_d3d11.loadEXT(_loadedVersion, platform);
152                 derelict.opencl.cl_dx9_media_sharing.loadEXT(_loadedVersion, platform);
153             }
154         }
155     }
156 
157     protected
158     {
159         this()
160         {
161             super(libNames);
162         }
163 
164         override void loadSymbols()
165         {
166             // OpenCL 1.0
167             bindFunc(cast(void**)&clGetPlatformIDs, "clGetPlatformIDs");
168             bindFunc(cast(void**)&clGetPlatformInfo, "clGetPlatformInfo");
169             bindFunc(cast(void**)&clGetDeviceIDs, "clGetDeviceIDs");
170             bindFunc(cast(void**)&clGetDeviceInfo, "clGetDeviceInfo");
171             bindFunc(cast(void**)&clCreateContext, "clCreateContext");
172             bindFunc(cast(void**)&clCreateContextFromType, "clCreateContextFromType");
173             bindFunc(cast(void**)&clRetainContext, "clRetainContext");
174             bindFunc(cast(void**)&clReleaseContext, "clReleaseContext");
175             bindFunc(cast(void**)&clGetContextInfo, "clGetContextInfo");
176             bindFunc(cast(void**)&clCreateCommandQueue, "clCreateCommandQueue");
177             bindFunc(cast(void**)&clRetainCommandQueue, "clRetainCommandQueue");
178             bindFunc(cast(void**)&clReleaseCommandQueue, "clReleaseCommandQueue");
179             bindFunc(cast(void**)&clGetCommandQueueInfo, "clGetCommandQueueInfo");
180             bindFunc(cast(void**)&clCreateBuffer, "clCreateBuffer");
181             bindFunc(cast(void**)&clRetainMemObject, "clRetainMemObject");
182             bindFunc(cast(void**)&clReleaseMemObject, "clReleaseMemObject");
183             bindFunc(cast(void**)&clGetSupportedImageFormats, "clGetSupportedImageFormats");
184             bindFunc(cast(void**)&clGetMemObjectInfo, "clGetMemObjectInfo");
185             bindFunc(cast(void**)&clGetImageInfo, "clGetImageInfo");
186             bindFunc(cast(void**)&clCreateSampler, "clCreateSampler");
187             bindFunc(cast(void**)&clRetainSampler, "clRetainSampler");
188             bindFunc(cast(void**)&clReleaseSampler, "clReleaseSampler");
189             bindFunc(cast(void**)&clGetSamplerInfo, "clGetSamplerInfo");
190             bindFunc(cast(void**)&clCreateProgramWithSource, "clCreateProgramWithSource");
191             bindFunc(cast(void**)&clCreateProgramWithBinary, "clCreateProgramWithBinary");
192             bindFunc(cast(void**)&clRetainProgram, "clRetainProgram");
193             bindFunc(cast(void**)&clReleaseProgram, "clReleaseProgram");
194             bindFunc(cast(void**)&clBuildProgram, "clBuildProgram");
195             bindFunc(cast(void**)&clGetProgramInfo, "clGetProgramInfo");
196             bindFunc(cast(void**)&clGetProgramBuildInfo, "clGetProgramBuildInfo");
197             bindFunc(cast(void**)&clCreateKernel, "clCreateKernel");
198             bindFunc(cast(void**)&clCreateKernelsInProgram, "clCreateKernelsInProgram");
199             bindFunc(cast(void**)&clRetainKernel, "clRetainKernel");
200             bindFunc(cast(void**)&clReleaseKernel, "clReleaseKernel");
201             bindFunc(cast(void**)&clSetKernelArg, "clSetKernelArg");
202             bindFunc(cast(void**)&clGetKernelInfo, "clGetKernelInfo");
203             bindFunc(cast(void**)&clGetKernelWorkGroupInfo, "clGetKernelWorkGroupInfo");
204             bindFunc(cast(void**)&clWaitForEvents, "clWaitForEvents");
205             bindFunc(cast(void**)&clGetEventInfo, "clGetEventInfo");
206             bindFunc(cast(void**)&clRetainEvent, "clRetainEvent");
207             bindFunc(cast(void**)&clReleaseEvent, "clReleaseEvent");
208             bindFunc(cast(void**)&clGetEventProfilingInfo, "clGetEventProfilingInfo");
209             bindFunc(cast(void**)&clFlush, "clFlush");
210             bindFunc(cast(void**)&clFinish, "clFinish");
211             bindFunc(cast(void**)&clEnqueueReadBuffer, "clEnqueueReadBuffer");
212             bindFunc(cast(void**)&clEnqueueWriteBuffer, "clEnqueueWriteBuffer");
213             bindFunc(cast(void**)&clEnqueueCopyBuffer, "clEnqueueCopyBuffer");
214             bindFunc(cast(void**)&clEnqueueReadImage, "clEnqueueReadImage");
215             bindFunc(cast(void**)&clEnqueueWriteImage, "clEnqueueWriteImage");
216             bindFunc(cast(void**)&clEnqueueCopyImage, "clEnqueueCopyImage");
217             bindFunc(cast(void**)&clEnqueueCopyImageToBuffer, "clEnqueueCopyImageToBuffer");
218             bindFunc(cast(void**)&clEnqueueCopyBufferToImage, "clEnqueueCopyBufferToImage");
219             bindFunc(cast(void**)&clEnqueueMapBuffer, "clEnqueueMapBuffer");
220             bindFunc(cast(void**)&clEnqueueMapImage, "clEnqueueMapImage");
221             bindFunc(cast(void**)&clEnqueueUnmapMemObject, "clEnqueueUnmapMemObject");
222             bindFunc(cast(void**)&clEnqueueNDRangeKernel, "clEnqueueNDRangeKernel");
223             bindFunc(cast(void**)&clEnqueueTask, "clEnqueueTask");
224             bindFunc(cast(void**)&clEnqueueNativeKernel, "clEnqueueNativeKernel");
225 
226             derelict.opencl.cl_ext.loadSymbols(&bindFunc);
227             derelict.opencl.cl_gl_ext.loadSymbols(&bindFunc);
228             derelict.opencl.cl_gl.loadSymbols(&bindFunc);
229 
230             if(Derelict_OS_Windows)
231             {
232                 derelict.opencl.cl_d3d10.loadSymbols(&bindFunc);
233                 derelict.opencl.cl_d3d11.loadSymbols(&bindFunc);
234                 derelict.opencl.cl_dx9_media_sharing.loadSymbols(&bindFunc);
235             }
236 
237             _loadedVersion = CLVersion.CL10;
238         }
239     }
240 
241     private
242     {
243         CLVersion _loadedVersion;
244     }
245 }
246 
247 __gshared DerelictCLLoader DerelictCL;
248 
249 shared static this()
250 {
251     DerelictCL = new DerelictCLLoader;
252 }